\section{\SignedNumbersSectionName}
\label{sec:signednumbers}
\myindex{Signed numbers}

\newcommand{\URLS}{\href{http://go.yurichev.com/17117}{wikipedia}}

Методов представления чисел со знаком \q{плюс} или \q{минус} несколько\footnote{\URLS}, 
но в компьютерах обычно применяется метод \q{дополнительный код} или \q{two's complement}.

Вот таблица некоторых значений байтов:

\label{signed_tbl}
\begin{center}
\begin{tabular}{ | l | l | l | l | }
\hline
\HeaderColor двоичное & \HeaderColor шестнадцатеричное & \HeaderColor беззнаковое & \HeaderColor знаковое \\
\hline
01111111 & 0x7f & 127 & 127 \\
\hline
01111110 & 0x7e & 126 & 126 \\
\hline
\multicolumn{4}{ |c| }{...} \\
\hline
00000110 & 0x6 & 6 & 6 \\
\hline
00000101 & 0x5 & 5 & 5 \\
\hline
00000100 & 0x4 & 4 & 4 \\
\hline
00000011 & 0x3 & 3 & 3 \\
\hline
00000010 & 0x2 & 2 & 2 \\
\hline
00000001 & 0x1 & 1 & 1 \\
\hline
00000000 & 0x0 & 0 & 0 \\
\hline
11111111 & 0xff & 255 & -1 \\
\hline
11111110 & 0xfe & 254 & -2 \\
\hline
11111101 & 0xfd & 253 & -3 \\
\hline
11111100 & 0xfc & 252 & -4 \\
\hline
11111011 & 0xfb & 251 & -5 \\
\hline
11111010 & 0xfa & 250 & -6 \\
\hline
\multicolumn{4}{ |c| }{...} \\
\hline
10000010 & 0x82 & 130 & -126 \\
\hline
10000001 & 0x81 & 129 & -127 \\
\hline
10000000 & 0x80 & 128 & -128 \\
\hline
\end{tabular}
\end{center}

\myindex{x86!\Instructions!JA}
\myindex{x86!\Instructions!JB}
\myindex{x86!\Instructions!JL}
\myindex{x86!\Instructions!JG}
Разница в подходе к знаковым/беззнаковым числам, собственно, нужна потому что, например, 
если представить \TT{0xFFFFFFFE} и \TT{0x00000002} как беззнаковое, то первое число (4294967294) больше второго (2). 
Если их оба представить как знаковые, то первое будет $-2$, которое, разумеется, меньше чем второе (2).
Вот почему инструкции для условных переходов~(\myref{sec:Jcc}) представлены в обоих версиях ~--- 
и для знаковых сравнений (например, \JG, \JL) и для беззнаковых (\JA, \JB).

Для простоты, вот что нужно знать:

\begin{itemize}
\item Числа бывают знаковые и беззнаковые.

\item Знаковые типы в \CCpp:

  \begin{itemize}
    \item \TT{int64\_t} (-9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807) 
	  (-~9.2..~9.2 квинтиллионов) или \\
                \TT{0x8000000000000000..0x7FFFFFFFFFFFFFFF}),
    \item \Tint (-2,147,483,648..2,147,483,647 (-~2.15..~2.15Gb) или \\
	    \TT{0x80000000..0x7FFFFFFF}),
    \item \Tchar (-128..127 или \TT{0x80..0x7F}),
    \item \TT{ssize\_t}.
   \end{itemize}

	Беззнаковые:
  \begin{itemize}
	  \item \TT{uint64\_t} (0..18,446,744,073,709,551,615 
		  (~18 квинтиллионов) или \TT{0..0xFFFFFFFFFFFFFFFF}),
   \item \TT{unsigned int} (0..4,294,967,295 (~4.3Gb) или \TT{0..0xFFFFFFFF}),
   \item \TT{unsigned char} (0..255 или \TT{0..0xFF}), 
   \item \TT{size\_t}.
  \end{itemize}

\item У знаковых чисел знак определяется \ac{MSB}: 1 означает \q{минус}, 0 означает \q{плюс}.

\item Преобразование в б\'{о}льшие типы данных обходится легко:

	\myref{subsec:sign_extending_32_to_64}.

\label{sec:signednumbers:negation}
\item Изменить знак легко: просто инвертируйте все биты и прибавьте 1.
Мы можем заметить, что число другого знака находится на другой стороне на том же расстоянии от нуля.
Прибавление единицы необходимо из-за присутствия нуля посредине.

\myindex{x86!\Instructions!IDIV}
\myindex{x86!\Instructions!DIV}
\myindex{x86!\Instructions!IMUL}
\myindex{x86!\Instructions!MUL}
\myindex{x86!\Instructions!CBW}
\myindex{x86!\Instructions!CWD}
\myindex{x86!\Instructions!CWDE}
\myindex{x86!\Instructions!CDQ}
\myindex{x86!\Instructions!CDQE}
\myindex{x86!\Instructions!MOVSX}
\myindex{x86!\Instructions!SAR}
\item Инструкции сложения и вычитания работают одинаково хорошо и для знаковых и для беззнаковых значений.
	Но для операций умножения и деления, в x86 имеются разные инструкции:
	\TT{IDIV}/\TT{IMUL} для знаковых и \TT{DIV}/\TT{MUL} для беззнаковых.

\item Еще инструкции работающие со знаковыми числами:\\
	\TT{CBW/CWD/CWDE/CDQ/CDQE} (\myref{ins:CBW_CWD_etc}), \TT{MOVSX} (\myref{MOVSX}), \TT{SAR} (\myref{ins:SAR}).
\end{itemize}

Таблица некоторых отрицательных и положительных значений (\ref{signed_tbl}) напоминает термометр со шкалой по Цельсию.
Вот почему сложение и вычитание работает одинаково хорошо и для знаковых и беззнаковых чисел:
если первое слагаемое представить как отметку на термометре, и нужно прибавить второе слагаемое,
и оно положительне, то мы просто поднимаем отметку вверх на значение второго слагаемого.
Если второе слагаемое отрицательное, то мы опускаем отметку вниз на абсолютное значение от второго слагаемого.

Сложение двух отрицательных чисел работает так.
Например, нужно сложить -2 и -3 используя 16-битные регистры.
-2 и -3 это 0xfffe и 0xfffd соответственно.
Если сложить эти два числа как беззнаковые, то получится 0xfffe+0xfffd=0x1fffb.
Но мы работаем с 16-битными регистрами, так что результат \IT{обрезается}, первая единица выкидывается,
остается 0xfffb, а это -5.
Это работает потому что -2 (или 0xfffe) можно описать простым русским языком так:
``в этом значении не достает двух до максимального значения в регистре + 1''.
-3 можно описать ``\dots не достает трех до \dots''.
Максимальное значение 16-битного регистра + 1 это 0x10000.
При складывании двух чисел, и \IT{обрезании} по модулю $2^{16}$, \IT{не хватать} будет $2+3=5$.

% subsections:
\input{fundamentals/MUL_IMUL_RU}
\input{fundamentals/one_more_RU}

